<?php

namespace app\admin\controller;

use app\admin\model\Admin;
use app\admin\model\Menu;
use app\admin\model\Role;
use app\admin\service\AdminService;
use app\admin\validate\AdminValidate;
use common\apidoc\Definitions;
use common\enum\ResultCode;
use hg\apidoc\annotation as Apidoc;
use support\Request;
use support\Response;
use support\Container;
use Tinywan\ExceptionHandler\Exception\BadRequestHttpException;

#[Apidoc\Title("管理员管理")]
class AdminController extends BaseController
{
    private AdminService $service;
    protected AdminValidate $validate;

    public function __construct()
    {
        $this->service = Container::get(AdminService::class);
        $this->validate = Container::get(AdminValidate::class);
    }

    #[Apidoc\Title("管理员列表")]
    #[Apidoc\Url("admin/admin/index")]
    #[Apidoc\Method("GET")]
    #[Apidoc\Query(ref: [Definitions::class, "pagingQueryParam"])]
    #[Apidoc\Query("user_name", type: "string", desc: "管理员名称")]
    #[Apidoc\Query("mobile", type: "string", desc: "手机号")]
    #[Apidoc\Query("email", type: "string", desc: "邮箱")]
    #[Apidoc\Query("status", type: "int", desc: "状态:0=禁用,1=启用")]
    #[Apidoc\Returned(ref: [Definitions::class, "pagingReturnParam"])]
    #[Apidoc\Returned("list", type: "array", ref: Admin::class, desc: "管理员列表")]
    public function index(Request $request): Response
    {
        $params = [
            'page' => $request->get('page', 1),
            'limit' => $request->get('limit', 10),
            'user_name' => $request->get('user_name', ''),
            'mobile' => $request->get('mobile', ''),
            'email' => $request->get('email', ''),
            'status' => $request->get('status', ''),
        ];
        if (!$this->validate->check($params, 'index')) {
            throw new BadRequestHttpException($this->validate->getError());
        }
        $result = $this->service->getList($params);
        return $this->success($result);
    }

    #[Apidoc\Title("管理员详情")]
    #[Apidoc\Url("admin/admin/info")]
    #[Apidoc\Method("GET")]
    #[Apidoc\Query("id", type: "int", require: true, desc: "管理员ID")]
    #[Apidoc\Returned(type: "object", ref: Admin::class, desc: "管理员详情")]
    #[Apidoc\Returned('roles', type: "array", ref: Role::class, desc: "角色列表", children: [
        ['name' => 'menus', 'type' => 'array', 'ref' => Menu::class, 'desc' => '菜单列表'],
    ])]
    #[Apidoc\Returned('flat_menus', type: "array", ref: Menu::class, desc: "菜单列表")]
    public function info(Request $request): Response
    {
        $id = $request->get('id', $request->admin['id']);
        if (!$this->validate->check(['id' => $id], 'info')) {
            throw new BadRequestHttpException($this->validate->getError());
        }
        $result = $this->service->getInfo($id);
        return $this->success($result);
    }

    #[Apidoc\Title("添加管理员")]
    #[Apidoc\Url("admin/admin/create")]
    #[Apidoc\Method("POST")]
    #[Apidoc\Param("user_name", type: "string", require: true, desc: "管理员名称")]
    #[Apidoc\Param("mobile", type: "string", require: true, desc: "手机号")]
    #[Apidoc\Param("email", type: "string", require: false, desc: "邮箱")]
    #[Apidoc\Param("password", type: "string", require: true, desc: "密码")]
    #[Apidoc\Param("avatar", type: "string", require: false, desc: "头像")]
    #[Apidoc\Param("status", type: "int", require: false, default: 1, desc: "状态:0=禁用,1=启用")]
    #[Apidoc\Returned(type: "object", ref: Admin::class, desc: "管理员详情")]
    public function create(Request $request): Response
    {
        $data = [
            'user_name' => $request->post('user_name'),
            'mobile' => $request->post('mobile'),
            'email' => $request->post('email'),
            'password' => $request->post('password'),
            'avatar' => $request->post('avatar'),
            'status' => $request->post('status', 1),
        ];
        if (!$this->validate->check($data, 'create')) {
            throw new BadRequestHttpException($this->validate->getError());
        }
        $result = $this->service->create($data);
        return $this->success($result, ResultCode::CREATE_SUCCESS->getDescription());
    }

    #[Apidoc\Title("更新管理员")]
    #[Apidoc\Url("admin/admin/update")]
    #[Apidoc\Method("POST")]
    #[Apidoc\Param("id", type: "int", require: true, desc: "管理员ID")]
    #[Apidoc\Param("user_name", type: "string", require: false, desc: "管理员名称")]
    #[Apidoc\Param("mobile", type: "string", require: false, desc: "手机号")]
    #[Apidoc\Param("email", type: "string", require: false, desc: "邮箱")]
    #[Apidoc\Param("password", type: "string", require: false, desc: "密码")]
    #[Apidoc\Param("avatar", type: "string", require: false, desc: "头像")]
    #[Apidoc\Param("status", type: "int", require: false, desc: "状态:0=禁用,1=启用")]
    public function update(Request $request): Response
    {
        $id = $request->post('id');
        $data = [
            'user_name' => $request->post('user_name'),
            'mobile' => $request->post('mobile'),
            'email' => $request->post('email'),
            'password' => $request->post('password'),
            'avatar' => $request->post('avatar'),
            'status' => $request->post('status'),
        ];
        $data = array_filter(array_merge(['id' => $id], $data), function ($value) {
            return !empty($value);
        });
        if (!$this->validate->check($data, 'update')) {
            throw new BadRequestHttpException($this->validate->getError());
        }
        $result = $this->service->update($id, $data);
        return $this->success($result, ResultCode::UPDATE_SUCCESS->getDescription());
    }

    #[Apidoc\Title("删除管理员")]
    #[Apidoc\Url("admin/admin/delete")]
    #[Apidoc\Method("POST")]
    #[Apidoc\Param("id", type: "int", require: true, desc: "管理员ID")]
    public function delete(Request $request): Response
    {
        $id = $request->post('id');
        if (!$this->validate->check(['id' => $id], 'delete')) {
            throw new BadRequestHttpException($this->validate->getError());
        }
        $this->service->delete($id);
        return $this->success(null, ResultCode::DELETE_SUCCESS->getDescription());
    }

    #[Apidoc\Title("管理员授权角色")]
    #[Apidoc\Url("admin/admin/grantRoles")]
    #[Apidoc\Method("POST")]
    #[Apidoc\Param("adminId", type: "int", require: true, desc: "管理员ID")]
    #[Apidoc\Param("roleIds", type: "array", require: false, desc: "角色ID列表")]
    #[Apidoc\Returned("attached", type: "array", desc: "已关联的角色ID列表")]
    #[Apidoc\Returned("detached", type: "array", desc: "已取消关联的角色ID列表")]
    public function grantRoles(Request $request): Response
    {
        $adminId = $request->post('adminId');
        $roleIds = $request->post('roleIds', []);
        if (!$this->validate->check(['id' => $adminId], 'grantRoles')) {
            throw new BadRequestHttpException($this->validate->getError());
        }
        $result = $this->service->grantRoles($adminId, $roleIds);
        return $this->success($result, '授权成功');
    }
}